using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using System.Linq;

namespace ClubWebsite
{
    public partial class PageEntry : System.Web.UI.UserControl
    {
        public delegate void EntryOptionClickedEventHandler(PageEntry entryControl);
        public event EntryOptionClickedEventHandler NewEntryAboveClicked;
        public event EntryOptionClickedEventHandler NewEntryBelowClicked;
        public event EntryOptionClickedEventHandler RemoveEntryClicked;
        public event EntryOptionClickedEventHandler AddEntryClicked;
        public event EntryOptionClickedEventHandler CancelAddEntryClicked;

        private Guid _entryID;
        public Guid EntryID
        {
            set
            {
                _entryID = value;
            }
            get
            {
                return _entryID;
            }
        }

        public enum Mode
        {
            View,
            CanEdit,
            Adding,
            Editing
        }
        private Mode _mode;
        public Mode CurrentMode
        {
            set
            {
                _mode = value;
            }
            get
            {
                return _mode;
            }
        }

        private string _html;
        public string HTML
        {
            get
            {
                return _html;
            }
            set
            {
                _html = value;
            }
        }

        private string _convertedHTML;
        public string ConvertedHTML
        {
            get
            {
                return _convertedHTML;
            }
            set
            {
                _convertedHTML = value;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // Get the value of the FCK Editor
            Page.ClientScript.RegisterOnSubmitStatement(FCKeditor1.GetType(), FCKeditor1.UniqueID, "FCKUpdateLinkedField('" + FCKeditor1.ClientID + "');");
            CreateControls(false);
            DisplayControls(CurrentMode);
        }

        private void CreateControls(bool forceControlCreation)
        {
            // Controls always need to be created
            plhContent.Controls.Clear();
            if (CurrentMode != Mode.Adding)
            {
                if (!IsPostBack)
                {
                    HTML = Functions.GetDatabaseDataContext()
                        .Entries
                        .Where(e => e.ID == EntryID)
                        .Select(e => e.HTML)
                        .Single();
                    if ((CurrentMode == Mode.CanEdit) || (CurrentMode == Mode.Adding) || (CurrentMode == Mode.Editing))
                    {
                        // Replace any floating columns with non-floats
                        HTML = Regex.Replace(HTML, @"(?<=<div\sclass=""page)(left|right)column(?=(\s|""))", "non$&");
                    }
                    FCKeditor1.Value = HTML;
                    ConvertedHTML = Functions.ConvertTextWithTagsIntoHTML(HTML, Page.Master);
                }
                Functions.ConvertTextWithTagsIntoControls(ConvertedHTML, plhContent, Page, true);
            }
        }

        private void DisplayControls(Mode mode)
        {
            if ((!IsPostBack) || (CurrentMode != mode) || (CurrentMode == Mode.Adding))
            {
                CurrentMode = mode;

                // Hide all controls
                foreach (Control control in UpdatePanel1.ContentTemplateContainer.Controls)
                {
                    control.Visible = false;
                }
                litDIVStart.Text = "<div class=\"entry\">";
                litDIVStart.Visible = true;
                litDIVEnd.Visible = true;

                if ((CurrentMode == Mode.View) || (CurrentMode == Mode.CanEdit))
                {
                    plhContent.Visible = true;
                }
                if ((CurrentMode == Mode.CanEdit) || (CurrentMode == Mode.Adding) || (CurrentMode == Mode.Editing))
                {
                    litDIVStart.Text = Regex.Replace(litDIVStart.Text, @"(?<=<div\sclass="")entry(?=(\s|""))", "$& entryedit");
                }
                if (CurrentMode == Mode.CanEdit)
                {
                    pnlEditOptionsHeader.Visible = true;
                }
                if (CurrentMode == Mode.Editing)
                {
                    pnlEditingOptionsHeader.Visible = true;
                    // Replace any floating columns with non-floats
                    //FCKeditor1.Value = Regex.Replace(Functions.GetEntriesRowByEntryID(EntryID).HTML, @"(?<=<div\sclass=""page)(left|right)column(?=(\s|""))", "non$&");
                    FCKeditor1.Visible = true;
                }
                if (CurrentMode == Mode.Adding)
                {
                    pnlAddingOptionsHeader.Visible = true;
                    if (!IsPostBack)
                    {
                        FCKeditor1.Value = "";
                    }
                    FCKeditor1.Visible = true;
                }
            }
        }

        protected void btnModify_Click(object sender, EventArgs e)
        {
            DisplayControls(Mode.Editing);
        }

        protected void btnNewAbove_Click(object sender, EventArgs e)
        {
            if (NewEntryAboveClicked != null)
            {
                NewEntryAboveClicked(this);
            }
        }

        protected void btnNewBelow_Click(object sender, EventArgs e)
        {
            if (NewEntryBelowClicked != null)
            {
                NewEntryBelowClicked(this);
            }
        }

        protected void btnRemove_Click(object sender, EventArgs e)
        {
            if (RemoveEntryClicked != null)
            {
                RemoveEntryClicked(this);
            }
        }

        protected void btnAdd_Click(object sender, EventArgs e)
        {
            HTML = Functions.ConvertUserTextToSafeText(FCKeditor1.Value);
            ConvertedHTML = Functions.ConvertTextWithTagsIntoHTML(HttpUtility.HtmlDecode(HTML), Page.Master);
            if (AddEntryClicked != null)
            {
                AddEntryClicked(this);
            }
        }

        protected void btnCancelAdd_Click(object sender, EventArgs e)
        {
            if (CancelAddEntryClicked != null)
            {
                CancelAddEntryClicked(this);
            }
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            // Save any changes to the database
            HTML = Functions.ConvertUserTextToSafeText(FCKeditor1.Value);
            using (MainDataClassesDataContext databaseDataContext = Functions.GetDatabaseDataContext())
            {
                Entry entry = databaseDataContext
                        .Entries
                        .Single(r => r.ID == EntryID);
                entry.HTML = HTML;
                if ((entry.HTML != "") && (entry.HTML != "null"))
                {
                    databaseDataContext.SubmitChanges();
                }
                else
                {
                    databaseDataContext.Entries.GetOriginalEntityState(entry);
                }
            }
            ConvertedHTML = Functions.ConvertTextWithTagsIntoHTML(HttpUtility.HtmlDecode(HTML), Page.Master);
            CreateControls(true);
            DisplayControls(Mode.CanEdit);
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            DisplayControls(Mode.CanEdit);
        }

        [Serializable()]
        private struct Properties
        {
            public Guid EntryID;
            public Mode CurrentMode;
            public string HTML;
            public string ConvertedHTML;
            public Properties(Guid entryID, Mode mode, string html, string convertedHTML)
            {
                EntryID = entryID;
                CurrentMode = mode;
                HTML = html;
                ConvertedHTML = convertedHTML;
            }
        }

        protected override object SaveControlState()
        {
            return new Properties(EntryID, CurrentMode, HTML, ConvertedHTML);
        }

        protected override void LoadControlState(object state)
        {
            if (state is Properties)
            {
                EntryID = ((Properties)state).EntryID;
                CurrentMode = ((Properties)state).CurrentMode;
                HTML = ((Properties)state).HTML;
                ConvertedHTML = ((Properties)state).ConvertedHTML;
            }
        }
    }
}